MethodHandle tmp1 = LINKER.downcallHandle(malloc_symbol, mallocDescriptor);
malloc_handle = tmp1;
+ MemorySegment free_symbol = SYM_LOOKUP.findOrThrow("free");
+ long free_address = free_symbol.address();
+ FunctionDescriptor setFreeFnDescriptor = FunctionDescriptor.ofVoid(JAVA_LONG);
+ MemorySegment set_free = SYM_LOOKUP.findOrThrow("HBSetFreeFn");
+ @SuppressWarnings("restricted")
+ MethodHandle set_free_handle = LINKER.downcallHandle(set_free, setFreeFnDescriptor);
+ try {
+ set_free_handle.invokeExact(free_address);
+ } catch (Throwable t) {
+ }
+
FunctionDescriptor createFaceDescriptor =
FunctionDescriptor.of(ADDRESS, ADDRESS);
MemorySegment create_face_symbol = SYM_LOOKUP.findOrThrow("HBCreateFace");
/*
- * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
typedef int (*GetTableDataFn) (int tag, char **dataPtr);
+typedef void (*ffm_free_t) (void *ptr);
+
+static ffm_free_t ffm_free_fn = NULL;
+
+/* We pass the address of "free" which was obtained by FFM so that it matches
+ * the malloc found by FFM
+ */
+#include <stdio.h>
+static void ffmfree(void *ptr) {
+ if (ffm_free_fn != NULL) {
+ ffm_free_fn(ptr);
+ } else {
+ free(ptr);
+ }
+}
+
static hb_blob_t *
reference_table(hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) {
*/
return hb_blob_create((const char *)tableData, length,
HB_MEMORY_MODE_WRITABLE,
- tableData, free);
+ tableData, ffmfree);
}
extern "C" {
+JDKEXPORT void HBSetFreeFn(void *free_fn) {
+ ffm_free_fn = (ffm_free_t)free_fn;
+}
+
JDKEXPORT hb_face_t* HBCreateFace(GetTableDataFn *get_data_upcall_fn) {
hb_face_t *face = hb_face_create_for_tables(reference_table, get_data_upcall_fn, NULL);